package com.swak.consistency.core.rpc.dubbo;

import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;

import java.lang.reflect.Method;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;

import com.swak.annotation.Tcc;
import com.swak.consistency.core.aspect.ConsistencyProceeding;

/**
 * 主要用户参数的传递
 * 
 * @author DELL
 */
@Activate(group = { CONSUMER })
public class ConsistencyTransmitFilter implements Filter {

	@Override
	@SuppressWarnings("rawtypes")
	public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
		Class<?> clazz = invoker.getInterface();
		Class[] args = invocation.getParameterTypes();
		Object[] arguments = invocation.getArguments();
		converterParamsClass(args, arguments);
		Method method = null;
		try {
			method = clazz.getMethod(invocation.getMethodName(), args);
		} catch (Exception e) {
		}

		// 这里应该判断所有的服务，不限于 Tcc
		if (method != null && method.isAnnotationPresent(Tcc.class)) {
			try {
				return (Result) ConsistencyProceeding.of().setTarget(clazz).setMethod(method).setArgs(arguments)
						.setProceeding(() -> {
							return invoker.invoke(invocation);
						}).transmit();
			} catch (Throwable e) {
				throw new RpcException("Tcc 执行异常：", e);
			}
		}
		return invoker.invoke(invocation);
	}

	@SuppressWarnings("rawtypes")
	private void converterParamsClass(final Class[] args, final Object[] arguments) {
		if (arguments == null || arguments.length < 1) {
			return;
		}
		for (int i = 0; i < arguments.length; i++) {
			if (arguments[i] != null) {
				args[i] = arguments[i].getClass();
			}
		}
	}
}
